package com.atgion.manager.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.atgion.manager.mapper.SysResourceMapper;
import com.atgion.manager.service.SysPermissionService;
import com.atgion.manager.service.SysResourceService;
import com.atgion.manager.service.SysRolePermissionService;
import com.atgion.manager.util.CglibUtil;
import com.atgion.manager.util.JwtTokenUtil;
import com.atgion.manager.util.RouteUtil;
import com.atgion.common.log.utils.SysUserDetail;
import com.atgion.spzx.model.bo.system.SysMenuBO;
import com.atgion.spzx.model.bo.system.SysPermissionBO;
import com.atgion.spzx.model.entity.system.SysPermission;
import com.atgion.spzx.model.entity.system.SysResource;
import com.atgion.spzx.model.entity.system.SysUser;
import com.atgion.spzx.model.vo.base.Meta;
import com.atgion.spzx.model.vo.base.Result;
import com.atgion.spzx.model.vo.base.ResultCode;
import com.atgion.spzx.model.vo.system.SysMenuPermissionVO;
import com.atgion.spzx.model.vo.system.SysMenuTreeVO;
import com.atgion.spzx.model.vo.system.SysMenuVO;
import com.atgion.spzx.model.vo.system.SysRoutesVO;
import com.atgion.common.log.utils.SecurityUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.atgion.exception.enums.DelStatusEnums;
import com.atgion.exception.enums.MenuTypeEnums;
import com.atgion.exception.enums.StatusEnums;
import com.atgion.exception.exception.GlobalException;
import com.atgion.exception.exception.GlobalExceptionEnum;
import com.atgion.exception.util.ExceptionUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class SysResourceServiceImpl extends ServiceImpl<SysResourceMapper, SysResource> implements SysResourceService {

    private final JwtTokenUtil jwtTokenUtil;
    private static final RouteUtil routeUtil = new RouteUtil();

    final UserDetailsService userDetailsService;

    @Autowired
    SysPermissionService sysPermissionService;


    @Autowired
    SysRolePermissionService sysRolePermissionService;

    @Override
    public Result<Map<String, Object>> getUserRoutes(String authorizationHeader) {
        if (authorizationHeader == null || !authorizationHeader.startsWith(jwtTokenUtil.getTokenHead())) {
            throw new GlobalException(GlobalExceptionEnum.ERROR_UNAUTHORIZED.getMessage());
        }

        Map<String, Object> map = new HashMap<>();

        try {
            String authToken = authorizationHeader.substring(jwtTokenUtil.getTokenHead().length());
            String username = jwtTokenUtil.getUserNameFromToken(authToken);
            if (username != null) {
                // 从数据库中获取用户信息
                SysUserDetail userDetails = (SysUserDetail) this.userDetailsService
                        .loadUserByUsername(username);

                String id = userDetails.getSysUser()
                        .getId().toString();

                List<SysResource> userRoutes = baseMapper.getUserRoutes(id);

                List<SysRoutesVO> routesVOList = routeUtil.processRoute(userRoutes);

                map.put("home", "home");
                map.put("routes", routesVOList);
                return Result.success(map);
            }
        } catch (Exception e) {
            log.info("获取资源信息异常: {}", e.getMessage());
            ExceptionUtil.throwEx(GlobalExceptionEnum.ERROR_GAIN_RESOURCE);
        }

        return Result.success();
    }

    @Override
    public Result<IPage<SysMenuVO>> getMenuList(Map<String, Object> params) {
        int pageNum = 1;
        int pageSize = 10;

        if (ObjUtil.isNotEmpty(params)) {
            pageSize = Integer.parseInt(String.valueOf(params.get("size")));
            pageNum = Integer.parseInt(String.valueOf(params.get("current")));
        }

        List<SysResource> list = getBaseQueryWrapper();

        List<SysMenuVO> menuVOS = convertSysResourceToMenuVO(list);

        List<SysMenuVO> processedMenuVOS = routeUtil.processMenu(menuVOS);

        List<SysPermission> permissionList = sysPermissionService.list();


        processedMenuVOS.forEach(record -> processMenuWithChildren(record, permissionList));


        List<SysMenuVO> pagedMenuVOS = paginate(processedMenuVOS, pageNum, pageSize);

        IPage<SysMenuVO> sysMenuVOIPage = new Page<>();
        sysMenuVOIPage.setRecords(pagedMenuVOS);
        sysMenuVOIPage.setCurrent(pageNum);
        sysMenuVOIPage.setSize(pageSize);
        sysMenuVOIPage.setTotal(processedMenuVOS.size());

        System.out.println(11);
        return Result.success(sysMenuVOIPage);
    }

    // 递归处理方法
    private void processMenuWithChildren(SysMenuVO menu, List<SysPermission> allPermissions) {
        // 1. 筛选当前菜单的权限
        List<SysPermission> currentPermissions = allPermissions.stream()
                .filter(item -> Objects.equals(menu.getId(), item.getMenuId()))
                .collect(Collectors.toList());
        menu.setSysPermissions(currentPermissions);

        // 2. 递归处理子菜单
        List<SysMenuVO> children = menu.getChildren();
        if (children != null && !children.isEmpty()) {
            children.forEach(child -> processMenuWithChildren(child, allPermissions));
        }
    }


    // Method to create base LambdaQueryWrapper
    private List<SysResource> getBaseQueryWrapper() {
        LambdaQueryWrapper<SysResource> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysResource::getIsDeleted, DelStatusEnums.DISABLE.getCode());
        lambdaQueryWrapper.notIn(SysResource::getMenuType, MenuTypeEnums.BASIC_MENU.getCode(), MenuTypeEnums.BUTTON.getCode());

        return list(lambdaQueryWrapper);
    }

    // Method to convert SysResource to SysMenuVO
    private List<SysMenuVO> convertSysResourceToMenuVO(List<SysResource> resources) {
        List<SysMenuVO> menuVOList = new ArrayList<>();
        resources.forEach(item -> {
            String meta = item.getMeta();
            SysMenuVO sysMenuVO = convertMetaJsonToSysMenuVO(meta);
            sysMenuVO.setId(item.getId());
            sysMenuVO.setParentId(item.getParentId());
            sysMenuVO.setUiPath(item.getUiPath());
            sysMenuVO.setMenuType(item.getMenuType());
            sysMenuVO.setStatus(item.getStatus());
            sysMenuVO.setMenuName(item.getMenuName());
            sysMenuVO.setRouteName(item.getRouteName());
            sysMenuVO.setRoutePath(item.getRoutePath());
            sysMenuVO.setComponent(item.getComponent());
            sysMenuVO.setWeight(item.getWeight());
            sysMenuVO.setCreateId(item.getCreateId());
            sysMenuVO.setCreateBy(item.getCreateBy());
            sysMenuVO.setCreateTime(item.getCreateTime());

            sysMenuVO.setUpdateId(item.getUpdateId());
            sysMenuVO.setUpdateBy(item.getUpdateBy());
            sysMenuVO.setUpdateTime(item.getUpdateTime());

            sysMenuVO.setIsDeleted(item.getIsDeleted());
            sysMenuVO.setDeleteTime(item.getDeleteTime());
            menuVOList.add(sysMenuVO);
        });
        return menuVOList;
    }

    // Method to paginate a list
    private <T> List<T> paginate(List<T> list, int pageNum, int pageSize) {
        int start = (pageNum - 1) * pageSize;
        int end = Math.min(start + pageSize, list.size());
        return list.subList(start, end);
    }

    public static SysMenuVO convertMetaJsonToSysMenuVO(String metaJson) {
        // 创建Meta对象并填充属性
        Meta meta = new Meta(metaJson);
        // 创建并初始化SysMenuVO对象
        SysMenuVO sysMenuVO = new SysMenuVO();
        // 将Meta对象的属性赋值给SysMenuVO对象
        BeanUtil.copyProperties(meta, sysMenuVO, false);

        return sysMenuVO;
    }

    @Override
    public Result<List<SysRoutesVO>> getConstantRoutes() {

        LambdaQueryWrapper<SysResource> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysResource::getIsDeleted, DelStatusEnums.DISABLE.getCode());
        lambdaQueryWrapper.eq(SysResource::getMenuType, MenuTypeEnums.BASIC_MENU.getCode());

        List<SysResource> list = list(lambdaQueryWrapper);

        List<SysRoutesVO> routesVOList = routeUtil.processRoute(list);
        return Result.success(routesVOList);
    }

    @Override
    public List<String> getUserPermissions(Long id) {
        return baseMapper.getUserPermissions(id);
    }

    @Override
    public Result<List<String>> getAllPages() {
        List<SysResource> list = getBaseQueryWrapper();

        List<String> routeNames = list.stream()
                .map(SysResource::getRouteName)
                .collect(Collectors.toList());

        return Result.success(routeNames);
    }

    @Override
    public Result<List<SysMenuTreeVO>> getMenuTree() {
        try {
            List<SysResource> userRoutes = getBaseQueryWrapper();
            List<SysMenuTreeVO> menuTree = routeUtil.getMenuTree(userRoutes);
            return Result.success(menuTree);
        } catch (Exception e) {
            log.info("获取菜单权限信息异常: {}", e.getMessage());
            throw new GlobalException(ResultCode.ERROR_GET_MENU_PERMISSIONS);
        }
    }

    @Override
    public Result<Integer> add(SysResource sysResource) {
        List<SysPermission> buttonsList = sysResource.getButtons();
        if (sysResource.getId() != null) {
            // update
            if (StrUtil.isNotEmpty(sysResource.getRoutePath())) {

//                LambdaQueryWrapper<SysResource> sysResourceLambdaQueryWrapper = new LambdaQueryWrapper<>();
//                sysResourceLambdaQueryWrapper.eq(SysResource::getIsDeleted, DelStatusEnums.DISABLE.getCode());
//                sysResourceLambdaQueryWrapper.eq(SysResource::getRoutePath, sysResource.getRoutePath());
//                List<SysResource> sysResources = list(sysResourceLambdaQueryWrapper);
//                if (sysResources.isEmpty()) {
//                    return Result.failed(ResultCode.ERROR_RESOURCE_EXISTENCE);
//                }
                sysPermissionService.removeByid(sysResource.getId());
                log.info("修改资源入参: {}", JSONUtil.parse(sysResource));
                LambdaUpdateWrapper<SysResource> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                lambdaUpdateWrapper.eq(SysResource::getId, sysResource.getId());
                update(sysResource, lambdaUpdateWrapper);
            }
        }else{
            // 随机8位字符串
            String randomString = RandomUtil.randomString(8);
            String uiPath;
            if (ObjUtil.isNotEmpty(sysResource.getParentId()) && sysResource.getParentId() != 0) {
                LambdaQueryWrapper<SysResource> sysResourceLambdaQueryWrapper = new LambdaQueryWrapper<>();
                sysResourceLambdaQueryWrapper.eq(SysResource::getIsDeleted, DelStatusEnums.DISABLE.getCode());
                sysResourceLambdaQueryWrapper.eq(SysResource::getId, sysResource.getParentId());
                List<SysResource> sysResources = list(sysResourceLambdaQueryWrapper);
                if (sysResources.isEmpty()) {
                    return Result.failed(ResultCode.ERROR_PARENT_RESOURCE_DOES_NOT_EXIST);
                }
                sysResource.setUiPath(sysResources.getFirst().getUiPath() + randomString + sysResource.getRoutePath());
            }
            uiPath = randomString + sysResource.getRoutePath();
            sysResource.setUiPath(uiPath);
            sysResource.setStatus(StatusEnums.ENABLE.getCode());
            sysResource.setIsDeleted(DelStatusEnums.DISABLE.getCode());
            log.info("新增资源入参: {}", JSONUtil.parse(sysResource));
            save(sysResource);
        }
        if(!sysResource.getEndTime().isEmpty()){
            sysRolePermissionService.removeBatchById(sysResource.getEndTime());
        }
        SysUser sysUser = SecurityUtil.getSysUser(); // 从自定义UserDetails实现类中提取
        if(!buttonsList.isEmpty()){
            for (SysPermission button : buttonsList) {
                if(button.getId()==null){
                    button.setCreateId(sysUser.getId());
                    button.setCreateTime(LocalDateTime.now());
                    button.setCreateBy(sysUser.getUserName());

                }else{
                    button.setUpdateId(sysUser.getId());
                    button.setUpdateTime(LocalDateTime.now());
                    button.setCreateBy(sysUser.getUserName());
                }
            }
            sysPermissionService.saveBatch(buttonsList);
            //批量添加
        }
        return Result.success();
    }

    @Override
    public void removeByid(List<Integer> ids) {

    }

    @Override
    public List<SysMenuPermissionVO> queryMenuPermissionList() {
        // 查询所有菜单信息
        LambdaQueryWrapper<SysResource> queryWrapper = new LambdaQueryWrapper<SysResource>()
                .eq(SysResource::getStatus, "1")
                .eq(SysResource::getMenuType, "2")
                .orderByAsc(SysResource::getWeight);
        List<SysMenuBO> sysMenuBOS = CglibUtil.convertList(baseMapper.selectList(queryWrapper), SysMenuBO::new);

        // 查询所有权限信息
        LambdaQueryWrapper<SysPermission> queryWrapperPermission = new LambdaQueryWrapper<SysPermission>()
                .eq(SysPermission::getStatus,"1");
        List<SysPermissionBO> sysPermissionBOS = CglibUtil.convertList(sysPermissionService.list(queryWrapperPermission), SysPermissionBO::new);

        // 根据菜单Id分组
        Map<Long, List<SysPermissionBO>> menuIdPermissionMap = sysPermissionBOS.stream()
                .collect(Collectors.groupingBy(SysPermissionBO::getMenuId));
        // 组装数据
        List<SysMenuPermissionVO> sysMenuPermissionVOS = Lists.newArrayList();
        // 遍历菜单信息
        sysMenuBOS.stream().map(menu -> {
            // 构建菜单权限对象
            SysMenuPermissionVO build = SysMenuPermissionVO.builder()
                    .menuId(menu.getId())
                    .menuName(menu.getMenuName())
//                    .i18nKey(menu.getI18nKey())
                    .build();
            // 根据菜单Id获取权限信息
            List<SysPermissionBO> permissions = menuIdPermissionMap.getOrDefault(menu.getId(), Lists.newArrayList());
            // 按照排序值排序
//            permissions.sort(Comparator.comparing(SysPermissionBO::getSort));
            // 构建按钮权限对象
            build.setButtons(CglibUtil.convertList(permissions, SysMenuPermissionVO.Button::new));
            return build;
        }).forEach(sysMenuPermissionVOS::add);
        return sysMenuPermissionVOS;
    }


}
